package com.sie.mp.util;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

import org.apache.http.util.EncodingUtils;

import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.ThumbnailUtils;
import android.net.Uri;
import android.os.Environment;
import android.os.StatFs;
import android.provider.BaseColumns;
import android.provider.MediaStore;
import android.provider.MediaStore.Images;
import android.util.Log;

public class FileUtil {
	private String SDPATH;
	public static boolean isSdCard = false;
	private static int FILESIZE = 1 * 1024;

	public String getSDPATH() {
		return SDPATH;
	}

	public FileUtil() {
		SDPATH = Environment.getExternalStorageDirectory().getAbsolutePath()
				+ "/";
	}

	public static boolean CheckSdCard(Context mContext, String RootPath) {
		if (!isSdCard) {
			// modComm.ShowMessage(mContext, "请安装SD卡");
			return false;
		}
		if (FileUtil.getAvailaleSize() < (1024 * 1024 * 10)) {// 小于10M
																// modComm.ShowMessage(mContext,
																// "SD卡空间不足");
			return false;
		}

		String cardRootPath = FileUtil.getSdPath() + RootPath;
		File dirFile = new File(cardRootPath);
		if (!dirFile.exists()) {
			dirFile.mkdirs();
		}

		return true;
	}

	/**
	 * 在SD卡上创建文件
	 * 
	 * @param fileName
	 * @return
	 * @throws IOException
	 */
	public static File createSDFile(String fileName) throws IOException {
		File file = new File(fileName);
		file.createNewFile();
		return file;
	}

	/**
	 * 在SD卡上创建目录
	 * 
	 * @param dirName
	 * @return
	 */
	public static File createSDDir(String dirName) {
		File dir = new File(dirName);
		if (!dir.exists()) {
			dir.mkdirs();
		}
		// dir.mkdir();
		return dir;
	}

	/**
	 * 判断SD卡上的文件夹是否存在
	 * 
	 * @param fileName
	 * @return
	 */
	public static boolean isFileExist(String fileName) {
		long s = 0;
		boolean isFile = false;
		File file = new File(fileName);
		if (file.exists()) {
			FileInputStream fis = null;
			try {
				fis = new FileInputStream(file);
				s = fis.available();
			} catch (FileNotFoundException e) {
				s = 0;
			} catch (IOException e) {
				s = 0;
			}
		}
		if (s > 0)
			isFile = true;
		return isFile;
	}

	/**
	 * 将一个InputStream里面的数据写入到SD卡中
	 * 
	 * @param path
	 * @param fileName
	 * @param input
	 * @return
	 */
	public static File write2SDFromInput(String path, String fileName,
			InputStream input) {
		File file = null;
		OutputStream output = null;
		try {
			createSDDir(path);
			file = createSDFile(path + fileName);
			output = new FileOutputStream(file);
			byte[] buffer = new byte[FILESIZE];
			while ((input.read(buffer)) != -1) {
				output.write(buffer);
			}
			output.flush();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				output.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return file;
	}

	/**
	 * 保存文本文件 到SD卡中
	 * 
	 * @param context
	 * @param path
	 *            文件路径
	 * @param fileName
	 *            文件名
	 * @param content
	 *            文件内容
	 * @return boolean
	 */
	public boolean write2SDFromStr(String path, String fileName, String content) {
		try {
			createSDDir(path);
			// 当文件名不是以.txt后缀名结尾时，自动加上.txt后缀
			if (!fileName.endsWith(".txt"))
				fileName = fileName + ".txt";

			File file = new File(path + fileName);
			OutputStream outstream = new FileOutputStream(file);
			OutputStreamWriter out = new OutputStreamWriter(outstream, "gb2312");
			out.write(content);
			out.close();

			return true;

		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}

	/**
	 * 路径组合方法
	 * 
	 * @param path1
	 * @param path2
	 * @return
	 */
	public static String combinePath(String path1, String path2) {
		if (path1 == null || "".equals(path1)) {
			return path2;
		}
		if (path2 == null || "".equals(path2)) {
			return path1;
		}
		String path = null;

		if (path1.endsWith(File.separator) && !path2.startsWith(File.separator)) {
			path = path1 + path2;
		} else if (!path1.endsWith(File.separator)
				&& path2.startsWith(File.separator)) {
			path = path1 + path2;
		} else if (!path1.endsWith(File.separator)
				&& !path2.startsWith(File.separator)) {
			path = path1 + File.separator + path2;
		} else if (path1.endsWith(File.separator)
				&& path2.startsWith(File.separator)) {
			path = path1 + path2.substring(1);
		}

		return path;
	}

	/**
	 * 取得文件名
	 * 
	 * @param fullpath
	 *            完整路径名
	 * @return
	 */
	public static String getFilename(String fullpath) {
		if (fullpath == null || fullpath == "") {
			return "";
		}
		int lastindex = fullpath.lastIndexOf(File.separator);
		if (lastindex == -1) {
			return "";
		}
		String name = fullpath.substring(lastindex + 1);

		return name;
	}

	/**
	 * 取得文件路径
	 * 
	 * @param fullpath
	 *            完整路径名
	 * @return
	 */
	public static String getFilePath(String fullpath) {
		if (fullpath == null || fullpath == "") {
			return "";
		}

		int lastindex = fullpath.lastIndexOf(File.separator);
		if (lastindex == -1) {
			return "";
		}
		String path = fullpath.substring(0, lastindex);

		return path;
	}

	/**
	 * 取得文件扩展名
	 * 
	 * @param filename
	 * @return
	 */
	public static String getExtFilename(String filename) {
		if (filename == null || filename == "") {
			return "";
		}
		int inx = filename.lastIndexOf(".");
		if (inx == -1) {
			return "";
		} else {
			String extname = filename.substring(inx + 1);
			return extname;
		}
	}

	/**
	 * 字符分割
	 * 
	 * @param srcStr
	 *            : 分割字符串
	 * @param pattern
	 *            : 分割符，如，# _等
	 * @param indexOrLast
	 *            : 取分割符的第一个还是最后一个，index 取 indexOf,否则取 lastIndexOf
	 * @param frontOrBack
	 *            : 取分割符前部分还是后部分：front 取分割符前部分，否则 取分割符后部分
	 * @return
	 */
	public static String spliteString(String srcStr, String pattern,
			String indexOrLast, String frontOrBack) {
		String result = "";
		int loc = -1;
		if (indexOrLast.equalsIgnoreCase("index")) {
			loc = srcStr.indexOf(pattern);
		} else {
			loc = srcStr.lastIndexOf(pattern);
		}
		if (frontOrBack.equalsIgnoreCase("front")) {
			if (loc != -1)
				result = srcStr.substring(0, loc);
		} else {
			if (loc != -1)
				result = srcStr.substring(loc + 1, srcStr.length());
		}
		return result;
	}

	/**
	 * 判断sd卡是否存在
	 * 
	 * @return boolean
	 */
	public static boolean sdCardExist() {
		return Environment.getExternalStorageState().equals(
				android.os.Environment.MEDIA_MOUNTED);
	}

	/**
	 * 取得sd卡文件路径
	 * 
	 * @return
	 */
	public static String getSdPath() {
		if (sdCardExist()) {
			return Environment.getExternalStorageDirectory().getPath();
		} else {
			return null;
		}
	}

	/**
	 * 取得空闲sd卡空间大小
	 * 
	 * @return
	 */
	public static long getAvailaleSize() {
		if (sdCardExist()) {
			StatFs stat = new StatFs(getSdPath());
			/* 获取block的SIZE */
			long blockSize = stat.getBlockSize();
			/* 空闲的Block的数量 */
			long availableBlocks = stat.getAvailableBlocks();
			/* 返回bit大小值 */
			return availableBlocks * blockSize;
			// (availableBlocks * blockSize)/1024 KIB 单位
			// (availableBlocks * blockSize)/1024 /1024 MIB单位
		} else {
			return 0;
		}
	}

	/**
	 * SD卡大小
	 * 
	 * @return
	 */
	public static long getAllSize() {
		if (sdCardExist()) {
			StatFs stat = new StatFs(getSdPath());
			/* 获取block的SIZE */
			long blockSize = stat.getBlockSize();
			/* 块数量 */
			long availableBlocks = stat.getBlockCount();
			/* 返回bit大小值 */
			return availableBlocks * blockSize;
		} else {
			return 0;
		}
	}
	
	/**
	 * 转换文件大小
	 * 
	 * @param fileS
	 * @return B/KB/MB/GB
	 */
	public static String formatFileSize(long fileS) {

		if (fileS == 0) {
			return "0.00B";
		}

		DecimalFormat dFormat = new DecimalFormat("#.00");

		String fileSizeString = "";

		if (fileS < 1024) {
			fileSizeString = dFormat.format((double) fileS) + "B";
		} else if (fileS < 1048576) {
			fileSizeString = dFormat.format((double) fileS / 1024) + "KB";
		} else if (fileS < 1073741824) {
			fileSizeString = dFormat.format((double) fileS / 1048576) + "MB";
		} else {
			fileSizeString = dFormat.format((double) fileS / 1073741824) + "GB";
		}
		return fileSizeString;
	}

	/**
	 * 检查文件后缀
	 * 
	 * @param checkItsEnd
	 * @param fileEndings
	 * @return
	 */
	public static boolean checkEndsWithInStringArray(String checkItsEnd,
			String[] fileEndings) {
		for (String aEnd : fileEndings) {
			if (checkItsEnd.endsWith(aEnd))
				return true;
		}
		return false;
	}

	/**
	 * 
	 * 返回本地文件列表
	 * 
	 * @param 本地文件夹路径
	 */
	public static List<File> getFileListByPath(String path) {
		File dir = new File(path);
		List<File> folderList = new ArrayList<File>();
		List<File> fileList = new ArrayList<File>();
		// 获取指定盘符下的所有文件列表。（listFiles可以获得指定路径下的所有文件，以数组方式返回）
		File[] files = dir.listFiles();
		// 如果该目录下面为空，则该目录的此方法执行
		if (files == null) {
			return folderList;
		}// 通过循环将所遍历所有文件
		for (int i = 0; i < files.length; i++) {
			if (!files[i].isHidden()) {
				if (files[i].isDirectory()) {
					folderList.add(files[i]);
				}
				if (files[i].isFile()) {
					fileList.add(files[i]);
				}
			}
		}
		folderList.addAll(fileList);
		return folderList;
	}

	/**
	 * 复制单个文件
	 * 
	 * @param oldPath
	 *            String 原文件路径 如：c:/fqf.txt
	 * @param newPath
	 *            String 复制后路径 如：f:/fqf.txt
	 * @return boolean
	 */
	public static boolean copyFile(String oldPath, String newPath) {
		boolean isok = true;
		try {
			int bytesum = 0;
			int byteread = 0;
			File oldfile = new File(oldPath);
			File newFile = new File(newPath);
			
			if (oldfile.exists()) { // 文件存在时
				final File to = new File(newPath);
				newFile.renameTo(to);
				to.delete();
				InputStream inStream = new FileInputStream(oldPath); // 读入原文件
				FileOutputStream fs = new FileOutputStream(newFile.getAbsolutePath());
				byte[] buffer = new byte[1024];
				int length;
				while ((byteread = inStream.read(buffer)) != -1) {
					bytesum += byteread; // 字节数 文件大小
					// System.out.println(bytesum);
					fs.write(buffer, 0, byteread);
				}
				fs.flush();
				fs.close();
				inStream.close();
			} else {
				isok = false;
			}
		} catch (Exception e) {
			// System.out.println("复制单个文件操作出错");
			// e.printStackTrace();
			isok = false;
		}
		return isok;
	}

	public static Bitmap getLoacalBitmap(String url) {
		try {
			BitmapFactory.Options options = new BitmapFactory.Options();
			options.inPreferredConfig = null;// Config.ARGB_8888;
			options.inPurgeable = true;// 允许可清除
			options.inInputShareable = true;// 以上options的两个属性必须联合使用才会有效果
			InputStream is = new FileInputStream(url);
			return BitmapFactory.decodeStream(is, null, options);

			// FileInputStream fis = new FileInputStream(url);
			// return BitmapFactory.decodeStream(fis);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			return null;
		}
	}

	public static Bitmap getVideoThumbnail(ContentResolver cr, Uri uri) {
		Bitmap bitmap = null;
		BitmapFactory.Options options = new BitmapFactory.Options();
		options.inDither = false;
		options.inPreferredConfig = Bitmap.Config.ARGB_8888;
		Cursor cursor = cr.query(uri,
				new String[] { BaseColumns._ID }, null, null, null);

		if (cursor == null || cursor.getCount() == 0) {
			return null;
		}
		cursor.moveToFirst();
		String videoId = cursor.getString(cursor
				.getColumnIndex(BaseColumns._ID)); // image id in
																// image table.s

		if (videoId == null) {
			return null;
		}
		cursor.close();
		long videoIdLong = Long.parseLong(videoId);
		bitmap = MediaStore.Video.Thumbnails.getThumbnail(cr, videoIdLong,
				Images.Thumbnails.MICRO_KIND, options);

		return bitmap;
	}

	private Bitmap getVideoThumbnail(String videoPath, int width, int height,
			int kind) {
		Bitmap bitmap = null;
		// 获取视频的缩略图
		bitmap = ThumbnailUtils.createVideoThumbnail(videoPath, kind);
		System.out.println("w" + bitmap.getWidth());
		System.out.println("h" + bitmap.getHeight());
		bitmap = ThumbnailUtils.extractThumbnail(bitmap, width, height,
				ThumbnailUtils.OPTIONS_RECYCLE_INPUT);
		return bitmap;
	}

	/**
	 * 复制文件
	 * 
	 * @param from来源文件
	 * @param to目标文件
	 * @return
	 * @throws Exception
	 */
	public static boolean copyFile(File from, File to) throws Exception {
		if (!from.exists()) {
			throw new Exception("被拷贝文件不存在");
		}
		InputStream is = new FileInputStream(from);
		OutputStream out = new FileOutputStream(to);
		return copyFile(is, out);
	}

	/**
	 * 流式文件复制
	 * 
	 * @param is输入流
	 * @param out输出流
	 * @return
	 * @throws IOException
	 */
	public static boolean copyFile(InputStream is, OutputStream out)
			throws IOException {
		if (is != null && out != null) {
			byte[] b = new byte[1024];
			int len = 0;
			while ((len = is.read(b)) != -1) {
				out.write(b, 0, len);
				return true;
			}
		}
		return false;
	}


	public static void unzipFiles(File file,String destDir) throws FileNotFoundException,IOException {
        //压缩文件
        File srcZipFile=file;
        //基本目录
        if(!destDir.endsWith("/")){
            destDir+="/";
        }
        FileUtil.deleteDirectory(destDir);
        String prefixion=destDir;
        
        //压缩输入流
        ZipInputStream zipInput=new ZipInputStream(new FileInputStream(srcZipFile));
        //压缩文件入口
        ZipEntry currentZipEntry=null;
        //循环获取压缩文件及目录
        while(null != (currentZipEntry=zipInput.getNextEntry())){
            //获取文件名或文件夹名
            String fileName=currentZipEntry.getName();
//            System.out.println("file Name:"+fileName);
            Log.v("filename",fileName);
            //构成File对象
            File tempFile=new File(prefixion+fileName);
            //父目录是否存在
            if(!tempFile.getParentFile().exists()){
                //不存在就建立此目录
                tempFile.getParentFile().mkdir();
            }
            //如果是目录，文件名的末尾应该有“/"
            if(currentZipEntry.isDirectory()){
                //如果此目录不在，就建立目录。
                if(!tempFile.exists()){
                    tempFile.mkdir();
                }
                //是目录，就不需要进行后续操作，返回到下一次循环即可。
                continue;
            }
            //如果是文件
            if(!tempFile.exists()){
                //不存在就重新建立此文件。当文件不存在的时候，不建立文件就无法解压缩。
                tempFile.createNewFile();
            }
            //输出解压的文件
            FileOutputStream tempOutputStream=new FileOutputStream(tempFile);

            //获取压缩文件的数据
            byte[] buffer=new byte[1024];
            int hasRead=0;
            //循环读取文件数据
            while((hasRead=zipInput.read(buffer))>0){
                tempOutputStream.write(buffer,0,hasRead);
            }
            tempOutputStream.flush();
            tempOutputStream.close();
        }
        zipInput.close();
    }

	/**
	 * 
	 * @param file输入文件
	 * @param code检测的安全码
	 *            (MD5/SHA)
	 * @return
	 */
	public static String getFileSecurityCode(File file, String code) {
		if (!file.isFile()) {
			return null;
		}
		MessageDigest digest = null;
		FileInputStream in = null;
		byte buffer[] = new byte[1024];
		int len;
		try {
			digest = MessageDigest.getInstance(code);
			in = new FileInputStream(file);
			while ((len = in.read(buffer)) != -1) {
				digest.update(buffer, 0, len);
			}
			BigInteger bigInt = new BigInteger(1, digest.digest());
			return bigInt.toString(16);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		} finally {
			try {
				in.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}

	}

	/**
	 * 根据SHA-1码以及MD5码判断两个文件是否相同
	 * 
	 * @param file1
	 * @param file2
	 * @return
	 */
	public static boolean isFileSame(File file1, File file2) {
		boolean isMd5Same = getFileSecurityCode(file1, "MD5").equals(
				getFileSecurityCode(file2, "MD5"));
		boolean isSHASame = getFileSecurityCode(file1, "SHA-1").equals(
				getFileSecurityCode(file2, "SHA-1"));
		return isMd5Same && isSHASame;
	}

	/**
	 * 将String以追加形式写入到文件
	 * 
	 * @param fileName
	 * @param content
	 * @throws Exception
	 */
	public static void writeString2FileEnd(String dirPath, String fileName,
			String writeData) throws Exception {
		writeString2File(dirPath, fileName, writeData, true);
	}

	/**
	 * 将String以覆盖的方式写入到文件中
	 * 
	 * @param file
	 * @param writeData
	 * @throws Exception
	 */
	public static void writeString2File(String dirPath, String fileName,
			String writeData) throws Exception {
		writeString2File(dirPath, fileName, writeData, false);
	}

	/**
	 * 私有文件夹下的文件存取（/data/data/包名/files）
	 * 
	 * @param ctx
	 * @param fileName
	 * @param message
	 */
	public static void writeString2AppFile(Context cxt, String fileName,
			String data) {
		writeString2AppFile(cxt, fileName, data, Context.MODE_PRIVATE);
	}

	/**
	 * 指定固定模式写入到 私有文件夹下的文件存取（/data/data/包名/files）
	 * 
	 * @param cxt
	 * @param fileName
	 * @param data
	 * @param mode
	 */
	public static void writeString2AppFile(Context cxt, String fileName,
			String data, int mode) {
		try {
			FileOutputStream fout = cxt.openFileOutput(fileName, mode);
			byte[] bytes = data.getBytes();
			fout.write(bytes);
			fout.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * @param ctx
	 * @param fileName
	 * @return
	 */
	public static String readAppFlie2String(Context ctx, String fileName) {
		String data = "";
		try {
			FileInputStream fin = ctx.openFileInput(fileName);
			int length = fin.available();
			byte[] buffer = new byte[length];
			fin.read(buffer);
			data = EncodingUtils.getString(buffer, "UTF-8");
			fin.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return data;
	}

	/**
	 * 
	 * @param dirPath目录名
	 *            ，存放在SD卡下，例如sdcard路径/a/b/c.txt,则dirPath为a/b/;fileName为c.txt
	 * @param fileName
	 *            ：文件名
	 * @param writeData
	 *            :待写入数据
	 * @param isAppend
	 *            :是否以追加形式写入
	 * @return
	 * @throws Exception
	 */
	public static boolean writeString2File(String dirPath, String fileName,
			String writeData, boolean isAppend) throws Exception {
		File file = new File(getSDPath() + dirPath + fileName);
		if (file.isDirectory()) {
			throw new Exception("File是一个目录");
		} else if (!file.exists()) {
			creatSDDir(file.getParent() + "/");
			file.createNewFile();
		}
		FileOutputStream fos = new FileOutputStream(file, isAppend);
		byte[] bytes = writeData.getBytes();
		fos.write(bytes);
		fos.close();
		return true;
	}

	public static File creatSDDir(String dirPath) {
		File dir = new File(dirPath);
		dir.mkdirs();
		return dir;
	}

	/**
	 * 
	 * @return 返回SD卡的路径 XX/sdcard之类
	 */
	public static String getSDPath() {
		File sdDir = null;
		boolean sdCardExist = Environment.getExternalStorageState().equals(
				Environment.MEDIA_MOUNTED); // 判断sd卡是否存在
		if (sdCardExist) {
			sdDir = Environment.getExternalStorageDirectory();// 获取跟目录
		}
		// 写路径记得带上"/"
		return sdDir.toString() + "/";
	}

	/**
	 * 默认输入流编码方式为utf-8,转字符串
	 * 
	 * @param is输入流
	 * @return 字符串
	 * @throws IOException
	 */
	public static String stream2string(InputStream is) throws IOException {
		return readStream2String(is, "utf-8");
	}

	/**
	 * 输入流转字符串
	 * 
	 * @param is输入流
	 * @param encode输入流的编码方式
	 * @return 返回字符串
	 * @throws IOException
	 */
	public static String readStream2String(InputStream is, String encode)
			throws IOException {
		if (is != null) {
			BufferedReader reader = new BufferedReader(new InputStreamReader(
					is, encode));
			StringBuilder sb = new StringBuilder();
			String line = null;
			while ((line = reader.readLine()) != null) {
				sb.append(line + "\n");
			}
			return sb.toString();
		}
		return null;
	}
	
	
    /**
     * 删除目录（文件夹）以及目录下的文件
     * @param   sPath 被删除目录的文件路径
     * @return  目录删除成功返回true，否则返回false
     */
    public static boolean deleteDirectory(String sPath) {
        //如果sPath不以文件分隔符结尾，自动添加文件分隔符
        if (!sPath.endsWith(File.separator)) {
            sPath = sPath + File.separator;
        }
        File dirFile = new File(sPath);
        //如果dir对应的文件不存在，或者不是一个目录，则退出
        if (!dirFile.exists() || !dirFile.isDirectory()) {
            return false;
        }
        boolean flag = true;
        //删除文件夹下的所有文件(包括子目录)
        File[] files = dirFile.listFiles();
        for (int i = 0; i < files.length; i++) {
            //删除子文件
            if (files[i].isFile()) {
                flag = deleteFile(files[i].getAbsolutePath());
                if (!flag) break;
            } //删除子目录
            else {
                flag = deleteDirectory(files[i].getAbsolutePath());
                if (!flag) break;
            }
        }
        if (!flag) return false;
        //删除当前目录
        if (dirFile.delete()) {
            return true;
        } else {
            return false;
        }
    }
    
    /**
     * 删除单个文件
     * @param   sPath    被删除文件的文件名
     * @return 单个文件删除成功返回true，否则返回false
     */
    public static boolean deleteFile(String sPath) {
        boolean flag = false;
        File file = new File(sPath);
        // 路径为文件且不为空则进行删除
        if (file.isFile() && file.exists()) {
            file.delete();
            flag = true;
        }
        return flag;
    }
    
}
